package com.vf.cloud.pass.mvc.biz.service.impl;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.kit.JsonKit;
import com.jfinal.kit.StrKit;
import com.vf.cloud.common.util.R;
import com.vf.cloud.common.util.UuidUtil;
import com.vf.cloud.pass.common.domain.biz.Project;
import com.vf.cloud.pass.common.domain.biz.Terminal;
import com.vf.cloud.pass.common.domain.biz.TerminalGpu;
import com.vf.cloud.pass.common.domain.biz.TerminalScene;
import com.vf.cloud.pass.common.factory.GPUFactory;
import com.vf.cloud.pass.common.vo.Order;
import com.vf.cloud.pass.common.vo.req.OrderParam;
import com.vf.cloud.pass.common.vo.req.StartUpParam;
import com.vf.cloud.pass.mvc.biz.service.IRender;

@Service
public class RenderImpl implements IRender {
	
	//配置GPU 需重启
	
	@Override
	public R<Order> AnyOrder(OrderParam param) {
		
		if (param == null) {
			return R.failed("参数必填.");
		}

		if (StrKit.isBlank(param.getOrder())) {
			return R.failed("参数必填.");
		}
		
		Project project=Project.dao.findById(param.getOrder());
		if(project==null) {
			return R.failed("应用不存在.");
		}
		
		//节点上已经有应用的
		List<TerminalScene> list=TerminalScene.dao.find("select * from "+TerminalScene.TABLE_NAME+" where scene_id=? and down_load_status='3' ",project.getSceneId());
		if(list==null || list.size()<=0) {
			return R.failed("应用暂未同步至渲染主机.");
		}
		
		Map<String,String> rendering=new HashMap<String,String>();
		for(TerminalScene terminalProject:list) {
			rendering.put(terminalProject.getTerminalId(), project.getSceneId());
		}
		
		R<String> applyR=GPUFactory.getInstance().apply(param.getOrder(),rendering,project);
		if(applyR.getCode()!=200) {
			return R.failed(applyR.getMessage());
		}
		
		String renderingKey=applyR.getResult();
		
		String[] renderingKeyArr=renderingKey.split("\\|");
		TerminalGpu terminalGpu=TerminalGpu.dao.findFirst("select * from "+TerminalGpu.TABLE_NAME+" where terminal_id=?  and gpu_index=?",renderingKeyArr[0],renderingKeyArr[1]);
		
		Terminal terminal=Terminal.dao.findById(renderingKeyArr[0]);
		if(terminal==null || StrKit.isBlank(terminal.getIp()) || StrKit.isBlank(terminal.getPort())) {
			
			//移除占用
			
			GPUFactory.getInstance().removeTimeout(renderingKey);
			
			return R.failed("渲染主机配置有误.");
		}
		
		TerminalScene terminalProject=TerminalScene.dao.findFirst("select * from "+TerminalScene.TABLE_NAME+" where terminal_id=? and scene_id=? ",renderingKeyArr[0],project.getSceneId());
		
		StartUpParam startUpParam=new StartUpParam();
		startUpParam.setSid(project.getId());
		startUpParam.setEio(UuidUtil.genKey());
		startUpParam.setWidth(param.getWidth());
		startUpParam.setHeight(param.getHeight());
		startUpParam.setIndex(Integer.parseInt(renderingKeyArr[1]));
		startUpParam.setBlock(Integer.parseInt(renderingKeyArr[2]));
		startUpParam.setUuid(terminalGpu.getId());
		startUpParam.setParameter(project.getParameter());
		startUpParam.setExeFilePath(String.format("%s/%s", terminal.getProjectPath(),terminalProject.getExeFilePath()));
		
		
		String nodeUrl = String.format("http://%s:%s/Renderers/Any/order", terminal.getIp(), terminal.getPort());
		HttpClient httpClient = new HttpClient();
		PostMethod method = new PostMethod(nodeUrl);
		try {
			RequestEntity requestEntity = new StringRequestEntity(JsonKit.toJson(startUpParam), "application/json", "UTF-8");
			method.setRequestEntity(requestEntity);
			int code = httpClient.executeMethod(method);
			if (code == 200) {
				JSONObject result = JSONObject.parseObject(new String(method.getResponseBody(), "UTF-8"));
				if (result.containsKey("code") && result.getInteger("code") == 200) {
					return R.ok(JSONObject.parseObject(result.getString("result"), Order.class));
				} else if (result.containsKey("code") && result.getInteger("code") == 500) {
					//移除占用
					GPUFactory.getInstance().removeTimeout(renderingKey);
					return R.failed(result.getString("message"));
				} else {
					//移除占用
					return R.failed(result.getString("message"));
				}
			} else {
				//移除占用
				return R.failed(String.format("网络异常:【%s】.", code));
			}
		} catch (IOException e) {
			//移除占用
			return R.failed(e.getMessage());
		}
	}

}
